<?php
namespace Ruben\Tcyun;

class TcIM
{
    private $sdkAppId;
    private $identifier;
    private $privateKeyFile;
    private $toolPath;

    function __construct($config)
    {
        $this->sdkAppId = $config['appid'];
        $this->identifier = $config['identifier'];
        $this->accountType = $config['account_type'];
//        $this->privateKey = $config['private_key'];
//        $this->publicKey = $config['private_key'];
        $this->privateKeyFile = $config['private_key_file'];
        $this->toolPath = $config['signature_tool_path'];
    }

    /**
     * 查询用户在线信息
     * {"ActionStatus": "OK", "ErrorInfo": "", "ErrorCode": 0, "QueryResult": [ { "To_Account": "@TLS#NOT_FOUND", "State": "Offline" }, { "To_Account": "201", "State": "Online" }, { "To_Account": "203", "State": "Online" }, { "To_Account": "225", "State": "Online" } ] }
     *
     * @param array $accounts 腾讯云通信的Identifier, 如['account1', 'account2']
     * @return void
     */
    public function queryState(array $accounts)
    {
        require_once('TcIMServerSdk/TimRestApi.php');
        $userSig = $this->genCmdSig($this->identifier);
        $api = new \TimRestAPI();
        $api->init($this->sdkAppId, $this->identifier);
        $api->set_user_sig($userSig);
        $reqData = [
            'To_Account' => $accounts,
        ];
        $reqData = json_encode($reqData);
        $ret = $api->api('openim', 'querystate', null, null, $reqData);
        $ret = json_decode($ret, true);
        if ($ret['ErrorCode'] == 0) {
            return $ret['QueryResult'];
        } else {
            // throw new \Exception($ret['ErrorInfo']);
            return false;   
        }
    }

    /**
     * 获取Sig，优先从缓存中读取，如果sig失效会自动替换
     * @param  string $privateKey 私钥
     * @param  string $publicKey  公钥
     * @param  int $expire 有效时长（秒）
     * @param  bool $isLatest 为true时不使用缓存
     * @return string             sig
     */
    public function genSig($privateKey, $publicKey, $expire = NULL, $isLatest = false)
    {
        $cacheName = 'tx_im_sig_' . $this->identifier;
        vendor('TcIMServerSdk.TLSSig');
        $signature = S($cacheName);
        $errMsg = '';
        $tlssig = new \TLSSigAPI();
        $tlssig->setAppid($this->sdkAppId);
        $tlssig->setPublicKey($publicKey);
        if ($isLatest === true
            || empty($signature)
            || ($tlssig->verifySig($signature['sig'], $this->identifier, $signature['gen_time'], $signature['expire'], $errMsg) === false)) {

            $tlssig->setPrivateKey($privateKey);
            $sig = $tlssig->genSig($this->identifier);
            $signature = [
                'sig' => $sig,
                'gen_time' => time(),
                'expire' => $expire,
            ];
            S($cacheName, $signature, $signature['expire']);
        }
        return $signature['sig'];
    }

    /**
     * 通过调用shell生成签名，注：需要到php.ini开启php的exec方法
     * @param  string  $privateKeyFile 私钥文件路径
     * @param  string  $toolPath       签名工具路径
     * @param  boolean $isLatest       是否强制刷新
     * @return string                  签名
     */
    public function genCmdSig($identifier, $isLatest = false)
    {
        $identifier = $identifier ?: $this->identifier;
        $cacheName = 'tc_im_sig_' . $identifier;
        /* 官方文档上说有效期为180，保险起见，减三天 */
        $isLatest = true;
        $expireAfter = 60 * 60 * 24 * 177;
        $signature = S($cacheName);
        if ($isLatest || empty($signature)) {
            require_once('TcIMServerSdk/TimRestApi.php');
            $api = new \TimRestAPI();
            $api->init($this->sdkAppId, $identifier);
            $userSig = $api->generate_user_sig($identifier, $expireAfter, $this->privateKeyFile, $this->toolPath);
            $signature = [
                'sig' => $userSig,
                'gen_time' => time(),
                'expire' => $expireAfter,
            ];
            S($cacheName, $signature, $expireAfter);
        }
        return $signature['sig'];
    }

    /**
     * 创建聊天室
     *
     * @param string $username TcIM用户名
     * @param [type] $roomName
     * @param string $type Public（公开群），Private（私密群），ChatRoom（聊天室），AVChatRoom（互动直播聊天室），BChatRoom（在线成员广播大群）
     * @return void
     */
    public function createChatroom($username, $roomName, $type = 'AVChatRoom')
    {
        require_once('TcIMServerSdk/TimRestApi.php');
        $api = new \TimRestAPI();
        $userSig = $this->genCmdSig();
        $api->init($this->sdkAppId, $this->identifier);
        $api->set_user_sig($userSig);
        $ret = $api->group_create_group($type, $roomName, $username);
        if ($ret['ErrorCode'] === 0) {
            return $ret['GroupId'];
        } else {
            $errMsg = $ret['ErrorInfo'];
            throw new \Exception($errMsg);
        }
    }


    /**
     * 改变成员身份，退出房间后会恢复，暂时无用
     *
     * @param string $account IM账号
     * @param   string $groupId 群组id
     * @param string $role Admin/Member 管理员/普通成员
     * @return void
     */
    public function changeRole($account, $groupId, $role)
    {
        require_once('TcIMServerSdk/TimRestApi.php');
        $api = new \TimRestAPI();
        $userSig = $this->genCmdSig();
        $api->set_user_sig($userSig);
        $api->init($this->sdkAppId, $this->identifier);
        $ret = $api->group_modify_group_member_info($groupId, $account, $role);
        if ($ret['ErrorCode'] === 0) {
            return true;
        } else {
            $errMsg = $ret['ErrorInfo'];
            throw new \Exception($errMsg);
        }
    }

    public function sendGift($group, $from, $gift, $count)
    {
        require_once('TcIMServerSdk/TimRestApi.php');
        $api = new \TimRestAPI();
        $userSig = $this->genCmdSig();
        $api->set_user_sig($userSig);
        $api->init($this->sdkAppId, $this->identifier);
        $payload = [
            'senderInfo' => $from,
            'userAction' => 6, // 礼物类型
            'msg' => $gift,
            'count' => $count,
            // 'msg' => [
            //     'gift' => $gift,
            //     'count' => $count,
            // ]
        ];
        $text = json_encode($payload);
        $ret = $api->group_send_group_msg($this->identifier, $group, $text);
        return $ret['ActionStatus'] === 'OK';
    } 

    public function joinLive($group, $from)
    {
        require_once('TcIMServerSdk/TimRestApi.php');
        $api = new \TimRestAPI();
        $userSig = $this->genCmdSig();
        $api->set_user_sig($userSig);
        $api->init($this->sdkAppId, $this->identifier);
        $payload = [
            'senderInfo' => $from,
            'userAction' => 2, // 礼物类型
            'msg' => $from['nickname'] . '加入房间',
            // 'count' => $count,
            // 'msg' => [
            //     'gift' => $gift,
            //     'count' => $count,
            // ]
        ];
        $text = json_encode($payload);
        $ret = $api->group_send_group_msg($this->identifier, $group, $text);
        return $ret['ActionStatus'] === 'OK';
    }

    public function groupGetGroupMemberInfo($groupId)
    {
        require_once('TcIMServerSdk/TimRestApi.php');
        $api = new \TimRestAPI();
        $userSig = $this->genCmdSig();
        $api->set_user_sig($userSig);
        $api->init($this->sdkAppId, $this->identifier);
        $ret = $api->group_get_group_member_info($groupId, $group, $text);
        if ($ret['ActionStatus'] === 'OK') {
            return array_column($ret['MemberList'], 'Member_Account');
        } else {
            return false;
        }
    }

    // public function quit($group, $from)
    // {
    //     require_once('TcIMServerSdk/TimRestApi.php');
    //     $api = new \TimRestAPI();
    //     $userSig = $this->genCmdSig();
    //     $api->set_user_sig($userSig);
    //     $api->init($this->sdkAppId, $this->identifier);
    //     $payload = [
    //         'senderInfo' => $from,
    //         'userAction' => 3, // 礼物类型
    //         'msg' => $from['nickname'] . '退出房间',
    //         // 'count' => $count,
    //         // 'msg' => [
    //         //     'gift' => $gift,
    //         //     'count' => $count,
    //         // ]
    //     ];
    //     $text = json_encode($payload);
    //     $ret = $api->group_send_group_msg($this->identifier, $group, $text);
    //     return $ret['ActionStatus'] === 'OK';
    // }

    public function accountImport($username, $nickname, $avatar)
    {
        require_once('TcIMServerSdk/TimRestApi.php');
        $api = new \TimRestAPI();
        $userSig = $this->genCmdSig();
        $api->set_user_sig($userSig);
        $api->init($this->sdkAppId, $this->identifier);
        $ret = $api->account_import($username, $nickname, $avatar);
        return $ret;
    }


}
